'use client';

import { useState, useEffect } from 'react';
import { Category } from '@/types';
import ImportExportToolbar from './ImportExportToolbar';
import { downloadCsv, downloadXls, downloadXlsx, parseCsv, parseExcelXml, parseXlsx } from '@/lib/importExportUtils';

export default function CategoryManager() {
  const [categories, setCategories] = useState<Category[]>([]);
  const [selectedCategory, setSelectedCategory] = useState<Category | null>(null);
  const [showModal, setShowModal] = useState(false);
  const [formData, setFormData] = useState({ name: '', parentId: '' });
  const [expandedCategories, setExpandedCategories] = useState<Set<string>>(new Set());
  const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());
  const [showDeleteMenu, setShowDeleteMenu] = useState(false);
  const [isImporting, setIsImporting] = useState(false);

  useEffect(() => {
    fetchCategories();
  }, []);

  useEffect(() => {
    const handleClickOutside = (e: MouseEvent) => {
      const target = e.target as HTMLElement;
      if (!target.closest('[data-menu-container]')) {
        setShowDeleteMenu(false);
      }
    };
    if (showDeleteMenu) {
      document.addEventListener('click', handleClickOutside);
      return () => document.removeEventListener('click', handleClickOutside);
    }
  }, [showDeleteMenu]);

  const fetchCategories = async () => {
    try {
      const res = await fetch('/api/categories');
      const data = await res.json();
      if (data.success) {
        setCategories(data.categories);
      }
    } catch (error) {
      console.error(error);
    }
  };

  const getAllCategoriesFlat = (cats: Category[]): Category[] => {
    let result: Category[] = [];
    cats.forEach(cat => {
      result.push(cat);
      if (cat.children) {
        result = result.concat(getAllCategoriesFlat(cat.children));
      }
    });
    return result;
  };

  const handleCreate = () => {
    setSelectedCategory(null);
    setFormData({ name: '', parentId: '' });
    setShowModal(true);
  };

  const handleEdit = (category: Category) => {
    setSelectedCategory(category);
    setFormData({ name: category.name, parentId: category.parentId || '' });
    setShowModal(true);
  };

  const handleDelete = async (id: string) => {
    if (!confirm('确定要删除这个分类吗？')) return;

    try {
      const res = await fetch(`/api/categories/${id}`, { method: 'DELETE' });
      const data = await res.json();
      if (data.success) {
        fetchCategories();
      } else {
        alert(data.message);
      }
    } catch (error) {
      alert('删除失败');
    }
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    try {
      if (selectedCategory) {
        // 更新
        const res = await fetch(`/api/categories/${selectedCategory.id}`, {
          method: 'PUT',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ name: formData.name }),
        });
        const data = await res.json();
        if (data.success) {
          setShowModal(false);
          fetchCategories();
        } else {
          alert(data.message);
        }
      } else {
        // 创建
        const res = await fetch('/api/categories', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ name: formData.name, parentId: formData.parentId || null }),
        });
        const data = await res.json();
        if (data.success) {
          setShowModal(false);
          fetchCategories();
        } else {
          alert(data.message);
        }
      }
    } catch (error) {
      alert('操作失败');
    }
  };


  const handleExportSelected = (format: 'csv' | 'xls' | 'xlsx') => {
    if (selectedIds.size === 0) return;
    const allFlat = getAllCategoriesFlat(categories);
    const selected = allFlat.filter(c => selectedIds.has(c.id));
    const headers = ['ID', '名称', '路径', '父ID'];
    const rows = selected.map(c => [c.id, c.name, c.path, c.parentId || '']);
    const filename = `categories_selected_${Date.now()}`;
    if (format === 'csv') {
      downloadCsv(`${filename}.csv`, headers, rows);
    } else if (format === 'xls') {
      downloadXls(`${filename}.xls`, headers, rows);
    } else {
      downloadXlsx(`${filename}.xlsx`, headers, rows);
    }
  };

  const handleExportAll = (format: 'csv' | 'xls' | 'xlsx') => {
    const allFlat = getAllCategoriesFlat(categories);
    if (allFlat.length === 0) return;
    const headers = ['ID', '名称', '路径', '父ID'];
    const rows = allFlat.map(c => [c.id, c.name, c.path, c.parentId || '']);
    const filename = `categories_all_${Date.now()}`;
    if (format === 'csv') {
      downloadCsv(`${filename}.csv`, headers, rows);
    } else if (format === 'xls') {
      downloadXls(`${filename}.xls`, headers, rows);
    } else {
      downloadXlsx(`${filename}.xlsx`, headers, rows);
    }
  };

  const deleteAllCategories = async () => {
    const allFlat = getAllCategoriesFlat(categories);
    if (allFlat.length === 0) return;
    if (!confirm(`确认删除全部 ${allFlat.length} 个分类吗？`)) return;
    if (!confirm('再次确认：该操作不可恢复，确定要删除全部分类吗？')) return;
    let failed = 0;
    const errors: string[] = [];
    const ordered = [...allFlat].reverse();
    try {
      for (const cat of ordered) {
        try {
          const res = await fetch(`/api/categories/${cat.id}`, { method: 'DELETE' });
          const data = await res.json();
          if (!data.success) {
            failed++;
            errors.push(`${cat.path}: ${data.message || '删除失败'}`);
          }
        } catch {
          failed++;
          errors.push(`${cat.path}: 网络错误`);
        }
      }
    } finally {
      setSelectedIds(new Set());
      await fetchCategories();
    }
    if (failed > 0) {
      alert(`删除完成，但有 ${failed} 个分类删除失败。${errors.length ? '\n\n前5条错误：\n' + errors.slice(0, 5).join('\n') : ''}`);
    }
  };


  const handleDownloadTemplate = (format: 'csv' | 'xls' | 'xlsx') => {
    const headers = ['名称', '父分类路径'];
    const example = ['Citrus', 'Fruit'];
    if (format === 'csv') {
      downloadCsv('categories_template.csv', headers, [example]);
    } else if (format === 'xls') {
      downloadXls('categories_template.xls', headers, [example]);
    } else {
      downloadXlsx('categories_template.xlsx', headers, [example]);
    }
  };

  const normalizeHeaderKey = (raw: string): string => {
    const trimmed = (raw || '').trim();
    const lower = trimmed.toLowerCase();
    // 支持中文和英文列名
    const map: Record<string, string> = {
      name: 'name', '名称': 'name',
      parentpath: 'parentpath', '父分类路径': 'parentpath', '父分类': 'parentpath',
    };
    return map[trimmed] ?? map[lower] ?? lower;
  };

  const importRows = async (rows: string[][]) => {
    if (rows.length === 0) { alert('文件为空'); return; }
    const [h0, ...data] = rows;
    const header = h0.map(h => normalizeHeaderKey(String(h)));
    const idxName = header.indexOf('name');
    const idxParentPath = header.indexOf('parentpath');
    if (idxName < 0 || idxParentPath < 0) { alert('缺少必要列：名称(或name), 父分类路径(或parentPath)'); return; }
    let ok = 0, failed = 0;
    const errors: string[] = [];
    for (let i = 0; i < data.length; i++) {
      const r = data[i];
      const name = r[idxName]?.trim();
      const parentPath = r[idxParentPath]?.trim();
      if (!name) { failed++; errors.push(`第${i + 2}行：名称 不能为空`); continue; }
      const allFlatNow = getAllCategoriesFlat(categories);
      const parent = parentPath ? allFlatNow.find(c => c.path === parentPath) : null;
      try {
        const res = await fetch('/api/categories', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ name, parentId: parent?.id || null })
        });
        const dataJson = await res.json();
        if (dataJson.success) { ok++; }
        else { failed++; errors.push(`第${i + 2}行：${dataJson.message || '创建失败'}`); }
      } catch {
        failed++;
        errors.push(`第${i + 2}行：网络错误`);
      }
    }
    await fetchCategories();
    alert(`导入完成：成功 ${ok} 条，失败 ${failed} 条${errors.length ? '\n\n前5个错误：\n' + errors.slice(0, 5).join('\n') : ''}`);
  };

  const handleImport = async (file: File, format: 'csv' | 'xls' | 'xlsx') => {
    setIsImporting(true);
    try {
      let rows: string[][];
      if (format === 'csv') {
        const text = await file.text();
        rows = parseCsv(text);
      } else if (format === 'xls') {
        const text = await file.text();
        rows = parseExcelXml(text);
      } else {
        rows = await parseXlsx(file);
      }
      await importRows(rows);
    } catch (e) {
      if (e instanceof Error && e.message.includes('xlsx')) {
        alert('请先安装 xlsx 库: npm install xlsx');
      } else {
        alert('导入失败');
      }
    } finally {
      setIsImporting(false);
    }
  };

  const toggleSelectAll = (checked: boolean) => {
    if (checked) {
      const ids = getAllCategoriesFlat(categories).map(c => c.id);
      setSelectedIds(new Set(ids));
    } else {
      setSelectedIds(new Set());
    }
  };

  const toggleExpand = (id: string) => {
    const newExpanded = new Set(expandedCategories);
    if (newExpanded.has(id)) {
      newExpanded.delete(id);
    } else {
      newExpanded.add(id);
    }
    setExpandedCategories(newExpanded);
  };

  const renderCategory = (category: Category, level: number = 0) => {
    const hasChildren = category.children && category.children.length > 0;
    const isExpanded = expandedCategories.has(category.id);
    const allFlat = getAllCategoriesFlat(categories);

    const collectDescendantIds = (cat: Category): string[] => {
      const ids: string[] = [];
      if (cat.children && cat.children.length) {
        for (const child of cat.children) {
          ids.push(child.id);
          ids.push(...collectDescendantIds(child));
        }
      }
      return ids;
    };

    return (
      <div key={category.id} style={{ marginBottom: '10px' }}>
        <div style={{
          display: 'flex',
          alignItems: 'center',
          padding: '10px',
          backgroundColor: '#f5f5f5',
          borderRadius: '5px',
          marginLeft: `${level * 20}px`,
        }}>
          <input
            type="checkbox"
            style={{ marginRight: '10px' }}
            checked={selectedIds.has(category.id)}
            onChange={(e) => {
              const affectedIds = new Set<string>([category.id, ...collectDescendantIds(category)]);
              setSelectedIds(prev => {
                const next = new Set(prev);
                if (e.target.checked) {
                  affectedIds.forEach(id => next.add(id));
                } else {
                  affectedIds.forEach(id => next.delete(id));
                }
                return next;
              });
            }}
          />
          {hasChildren && (
            <span
              style={{ marginRight: '10px', cursor: 'pointer' }}
              onClick={() => toggleExpand(category.id)}
            >
              {isExpanded ? '▼' : '▶'}
            </span>
          )}
          <span style={{ flex: 1 }}>{category.name} ({category.path})</span>
          <button
            className="btn btn-secondary"
            style={{ padding: '5px 10px', marginRight: '5px', fontSize: '14px' }}
            onClick={() => handleEdit(category)}
          >
            编辑
          </button>
          <button
            className="btn btn-danger"
            style={{ padding: '5px 10px', fontSize: '14px' }}
            onClick={() => handleDelete(category.id)}
          >
            删除
          </button>
        </div>
        {hasChildren && isExpanded && (
          <div>
            {category.children!.map(child => renderCategory(child, level + 1))}
          </div>
        )}
      </div>
    );
  };

  const allFlat = getAllCategoriesFlat(categories);

  return (
    <div>
      <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '20px' }}>
        <h2>分类管理</h2>
        <button className="btn btn-primary" onClick={handleCreate}>
          添加分类
        </button>
      </div>

      <div className="card">
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '15px', paddingBottom: '15px', borderBottom: '1px solid #eee' }}>
          <label style={{ display: 'flex', alignItems: 'center', gap: '6px', fontSize: '14px',paddingLeft: '10px' }}>
            <input
              type="checkbox"
              disabled={allFlat.length === 0}
              checked={allFlat.length > 0 && selectedIds.size === allFlat.length}
              onChange={(e) => toggleSelectAll(e.target.checked)}
            />
            全选
          </label>
          <div style={{ display: 'flex', gap: '10px', alignItems: 'center', flexWrap: 'wrap' }}>
            <div style={{ position: 'relative', display: 'inline-block' }} data-menu-container>
              <button className="btn btn-secondary" onClick={(e) => { e.stopPropagation(); setShowDeleteMenu(!showDeleteMenu); }}>
                删除 {showDeleteMenu ? '▼' : '▶'}
              </button>
              {showDeleteMenu && (
                <div style={{ position: 'absolute', top: '100%', right: 0, backgroundColor: 'white', border: '1px solid #ddd', borderRadius: '4px', boxShadow: '0 2px 8px rgba(0,0,0,0.1)', zIndex: 1000, minWidth: '180px', marginTop: '4px' }}>
                  <button
                    className="btn"
                    style={{ width: '100%', textAlign: 'left', padding: '8px', border: 'none', background: 'none', cursor: selectedIds.size === 0 ? 'not-allowed' : 'pointer', color: selectedIds.size === 0 ? '#ccc' : '#333', borderBottom: '1px solid #eee' }}
                    disabled={selectedIds.size === 0}
                    onClick={async () => {
                      setShowDeleteMenu(false);
                      if (selectedIds.size === 0) return;
                      if (!confirm(`确认删除选中的 ${selectedIds.size} 个分类吗？仅会删除没有子分类的项目。`)) return;
                      try {
                        const res = await fetch('/api/categories/bulk-delete', {
                          method: 'POST',
                          headers: { 'Content-Type': 'application/json' },
                          body: JSON.stringify({ ids: Array.from(selectedIds) }),
                        });
                        const data = await res.json();
                        if (data.success) {
                          if (data.skipped && data.skipped.length) {
                            alert(`已删除 ${data.deleted} 个分类；跳过 ${data.skipped.length} 个（含子分类，需先删除子分类）。`);
                          }
                          setSelectedIds(new Set());
                          fetchCategories();
                        } else {
                          alert(data.message || '批量删除失败');
                        }
                      } catch {
                        alert('批量删除失败');
                      }
                    }}
                  >
                    删除选中 ({selectedIds.size})
                  </button>
                  <button
                    className="btn"
                    style={{ width: '100%', textAlign: 'left', padding: '8px', border: 'none', background: 'none', cursor: allFlat.length === 0 ? 'not-allowed' : 'pointer', color: allFlat.length === 0 ? '#ccc' : '#dc3545', fontWeight: 'bold' }}
                    disabled={allFlat.length === 0}
                    onClick={async () => {
                      setShowDeleteMenu(false);
                      await deleteAllCategories();
                    }}
                  >
                    删除全部 ({allFlat.length})
                  </button>
                </div>
              )}
            </div>

            <ImportExportToolbar
              onExportSelected={handleExportSelected}
              onExportAll={handleExportAll}
              onImport={handleImport}
              onDownloadTemplate={handleDownloadTemplate}
              isImporting={isImporting}
              selectedCount={selectedIds.size}
              totalCount={allFlat.length}
            />
          </div>
        </div>
        {categories.length === 0 ? (
          <p>暂无分类</p>
        ) : (
          <div>
            {categories.map(category => renderCategory(category))}
          </div>
        )}
      </div>

      {showModal && (
        <div className="modal" onClick={() => setShowModal(false)}>
          <div className="modal-content" onClick={(e) => e.stopPropagation()}>
            <h2>{selectedCategory ? '编辑分类' : '添加分类'}</h2>
            <form onSubmit={handleSubmit}>
              <div style={{ marginBottom: '15px' }}>
                <label style={{ display: 'block', marginBottom: '5px', fontWeight: 'bold' }}>
                  分类名称
                </label>
                <input
                  type="text"
                  className="input"
                  value={formData.name}
                  onChange={(e) => setFormData({ ...formData, name: e.target.value })}
                  required
                />
              </div>
              {!selectedCategory && (
                <div style={{ marginBottom: '15px' }}>
                  <label style={{ display: 'block', marginBottom: '5px', fontWeight: 'bold' }}>
                    父分类（可选，留空为顶级分类）
                  </label>
                  <select
                    className="input"
                    value={formData.parentId}
                    onChange={(e) => setFormData({ ...formData, parentId: e.target.value })}
                  >
                    <option value="">无（顶级分类）</option>
                    {allFlat.map(cat => (
                      <option key={cat.id} value={cat.id}>{cat.path}</option>
                    ))}
                  </select>
                </div>
              )}
              <div style={{ display: 'flex', gap: '10px' }}>
                <button type="submit" className="btn btn-primary">
                  {selectedCategory ? '更新' : '创建'}
                </button>
                <button
                  type="button"
                  className="btn btn-secondary"
                  onClick={() => setShowModal(false)}
                >
                  取消
                </button>
              </div>
            </form>
          </div>
        </div>
      )}
    </div>
  );
}

